package com.first.computerstore.service;

import com.first.computerstore.dao.UserMapper;
import com.first.computerstore.query.UploadHeaderQuery;
import com.first.computerstore.utils.AssertUtil;
import com.first.computerstore.service.exception.InsertException;
import com.first.computerstore.service.exception.UserNotExistException;
import com.first.computerstore.service.exception.UsernameDuplicateException;
import com.first.computerstore.service.exception.WrongPasswordException;
import com.first.computerstore.utils.JsonResult;
import com.first.computerstore.service.exception.*;
import com.first.computerstore.utils.PasswordEncryptedUtils;
import com.first.computerstore.entity.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;

@Service
public class UserService {
    //注解操作
    @Resource
    private UserMapper userMapper;

    /**
     * Description : 处理用户注册
     * @param user 注册的用户信息
     * @return void
     **/
    public void userRegister(User user) {
        //需要先判断用户名是否在数据库中重复
        User queryUser = userMapper.queryUserByUsername(user.getUsername());

        //重复的情况下，抛出用户名重复异常
        if (queryUser != null){
            throw new UsernameDuplicateException("用户名已被注册");
        }

        //密码不能以明文方式存入数据库，需要进行加密操作
        //密码加密的实现： 盐值 + password + 盐值 ---> md5算法进行加密，连续加载三次 ---> 得到最终存入数据库的结果
        //盐值就是一个随机的字符串
        //记录旧密码
        String oldPassword = user.getPassword();
        //使用UUID获取时间戳创建盐值
        String salt = UUID.randomUUID().toString().toUpperCase();

        //记录此刻的盐值，用于以后做用户登录判断
        user.setSalt(salt);

        //进行加密操作
        String md5Password = PasswordEncryptedUtils.getPasswordByMD5(oldPassword, salt);

        //将加密后的密码设置为用户设置的密码
        user.setPassword(md5Password);

        //在执行插入操作之前对一些表字段进行补全
        //is_delete字段设置为0，表示未删除用户
        user.setIsDelete(0);

        //补全其余四个日志信息的字段
        Date currentTime = new Date();
        user.setCreatedUser(user.getUsername());
        user.setCreatedTime(currentTime);
        user.setModifiedUser(user.getUsername());
        user.setModifiedTime(currentTime);

        //不重复，调用插入方法,处理业务
        int result = userMapper.addUser(user);

        if (result == 0){ //判断服务器或数据库执行是否出现异常
            throw new InsertException("处理用户注册过程中，服务器或数据库执行出现异常");
        }
    }

    /**
     * Description : 处理用户登录
     * @param user 登录的用户信息
     * @return top.year21.computerstore.entity.User
     **/
    public User userLogin(User user) {
        //用户名
        String username = user.getUsername();
        //用户输入的密码
        String userPassword = user.getPassword();

        //查询登录用户是否在数据库中存在
        User loginUser = userMapper.queryUserByUsername(username);

        if (loginUser == null){ //为空代表用户名不存在
            throw new UserNotExistException("该用户名账户不存在");
        }

        //取得数据库查询返回用户的盐值和密码以及删除状态
        String salt = loginUser.getSalt();
        String databasePwd = loginUser.getPassword();
        Integer deleteStatus = loginUser.getIsDelete();

        //对用户输入的密码进行加密
        String md5PasswordBy = PasswordEncryptedUtils.getPasswordByMD5(userPassword, salt);

        //将加密后的字符和数据库查询的MD5进行校验
        if (!databasePwd.equals(md5PasswordBy)){
            throw new WrongPasswordException("该账户密码不正确");
        }

        //判断登录的用户账户是否已注销
        if (deleteStatus == 1){
            throw new UserNotExistException("该用户名账户不存在");
        }

        //密码正确返回查询的用户信息
        return loginUser;
    }

    public User queryUserByUid(Integer uid) {
        //根据uid查询用户信息返回给前端
        return userMapper.queryUserByUid(uid);
    }

    /**
     * 上传头像
     * @param uid
     * @param avatar
     * @param userName
     */
    public void uploadHeader(Integer uid, String avatar, String userName) {
        /* 参数校验 */
        AssertUtil.isTrue(null==uid,"用户id不能为空！");
        AssertUtil.isTrue(null == avatar || ""==avatar,"请选择要上传的头像！");
        AssertUtil.isTrue(null==userName||""==userName,"用户姓名不能为空！");

        /* 调用mapper中的方法 */
        Date modifiedTime = new Date();

        UploadHeaderQuery query = new UploadHeaderQuery();
        query.setAvatar(avatar);
        query.setUid(uid);
        query.setModifiedTime(new Date());
        query.setModifiedUser(userName);

        Integer row = userMapper.uploadHeaderByUid(query);
       AssertUtil.isTrue(row<1,"头像上传失败~(>_<)~");


    }

    /**
     *参数校验
     *  判断传入参数是否为空，前台完成了部分校验
     *  判断用户id是否为空
     *  判断用户对象是否存在
     *  判断数据库查询的密码是否与用户传入的密码一致
     *  判断原密码是否与数据库中密码一致
     *        不一致，提示 原密码有误，请重试
     *  判断新密码是否与原密码一致
     *          一致提示不能相同
     *  判断确认密码是否与新密码一致
     *          不一致提示 新密码与确认密码不同，请重新输入
     *  一致，密码验证通过
     *  将新密码更新到数据库中
     *          将新密码进行加密
     *          更新到数据库中
     *
     * @param oldPwd
     * @param password
     * @param rePwd
     * @return
     */
    public JsonResult selectPassWord(String oldPwd,String password,String rePwd,Integer uid){
        JsonResult jsonResult = new JsonResult<>();

        if (uid == null) {
            jsonResult.setStatus(4000);
            jsonResult.setMessage("用户ID不存在！");
            return jsonResult;
        }

        /*参数校验*/
        //使用加密工具类进行加密
        User temp = userMapper.queryUserByUid(uid);

        //判断用户id是否为空/判断用户对象是否存在
        if (null == temp){
            jsonResult.setStatus(4000);
            jsonResult.setMessage("用户不存在！");
            return jsonResult;
        }

        String oldMd5Pwd = PasswordEncryptedUtils.getPasswordByMD5(oldPwd, temp.getSalt());

        /*判断原密码是否与数据库中密码一致
         *        不一致，提示 原密码有误，请重试*/
        if (!temp.getPassword().equals(oldMd5Pwd)){
            jsonResult.setStatus(4000);
            jsonResult.setMessage("原密码输入错误，请重新输入！");
            return jsonResult;
        }
        /*判断新密码是否与原密码一致
         *          一致提示不能相同*/
        if (oldPwd.equals(password)){
            jsonResult.setStatus(4000);
            jsonResult.setMessage("原密码与新密码不能相同，请重新输入！");
            return jsonResult;
        }

        /*判断确认密码是否与新密码一致
         *          不一致提示 新密码与确认密码不同，请重新输入*/
        if (!password.equals(rePwd)){
            jsonResult.setStatus(4000);
            jsonResult.setMessage("新密码与确认密码不同，请重新输入！");
            return jsonResult;
        }


        //将新密码进行加密

        String newSalt = UUID.randomUUID().toString().toUpperCase();
        String newMd5Pwd = PasswordEncryptedUtils.getPasswordByMD5(password, newSalt);

        /*修改密码，返回受影响的行数*/
        int result = userMapper.updateUserPwd(newMd5Pwd,newSalt,uid);
        if (result > 0){

            jsonResult.setStatus(200);
            jsonResult.setMessage("密码验证通过,修改成功！");

        }else {
            jsonResult.setStatus(4000);
            jsonResult.setMessage(" 不可抗拒力！请重新修改！");
        }


        return jsonResult;
    }

    //更新个人资料
    public User updateUserInfo(String phone,String email,Integer gender,Integer uid,String username){
//        String username=getUsernameFromSession(session);
        //通过用户id查询用户是否存在
        User user = userMapper.queryUserByUid(uid);
        if (user==null){
            throw new UserNotExistException("用户不存在");
        }
        //判断受影响的行数
        int count = userMapper.updateUserInfo(phone, email, gender, uid,username);
        if (count<=0){
            throw  new UpdateException("更新失败");
        }
        return user;
    }
}
